package com.itheima.app.manager;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.itheima.app.config.StringRedisConfig;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.oss.OssTemplate;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Comment;
import com.itheima.domain.mongo.Movement;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.CommentService;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import com.itheima.vo.CommentVo;
import com.itheima.vo.MovementVo;
import com.itheima.vo.PageBeanVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Component
public class MovementManager {

    @DubboReference
    MovementService movementService;

    @Autowired
    OssTemplate ossTemplate;

    @DubboReference
    UserInfoService userInfoService;

    @DubboReference
    CommentService commentService;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Autowired
    MQMovementManager mqMovementManager;
    @Autowired
    private StringRedisConfig stringRedisConfig;

    public ResponseEntity save(MultipartFile[] imageContent, Movement movement) throws IOException {

        //查询redis中 看看是否有这个字段  如果有的话就返回提示
        if (stringRedisConfig.stringRedisTemplate2().hasKey("Free3"+UserHolder.get().getId())){
            return ResponseEntity.status(500).body("此用户处于冻结动态状态!");
        }

        //1.获取用户id
        Long userId = UserHolder.get().getId();

        //2.上传所有图片到oss上,且获取地址list
        //2.1 创建图片地址集合
        List<String> medias = new ArrayList<>();

        //2.2 遍历上传
        if (ArrayUtil.isNotEmpty(imageContent)) {
            for (MultipartFile file : imageContent) {
                //上传到oss上,获取图片路径
                String url = ossTemplate.upload(file.getOriginalFilename(), file.getInputStream());

                //将每个图片的路径放入地址list中
                medias.add(url);
            }
        }

        //3.封装movement对象
        //3.1 设置id
        movement.setId(ObjectId.get());
        //3.2 设置图片列表
        movement.setMedias(medias);
        //3.3 发布时间
        movement.setCreated(System.currentTimeMillis());
        //3.4 动态审核状态,正常来说应该是未审核
        //TODO 等我们完成内容审核之后,修改状态未审核
        movement.setState(0);
        //3.5 设置谁可以看 这个版本还未实现这个功能
        movement.setSeeType(1);
        //3.6 设置用户id
        movement.setUserId(userId);

        //4.远程调用service完成保存操作
        movementService.save(movement);

        //5.将动态的id放入mq中
        rabbitTemplate.convertAndSend("tanhua.movement.state",movement.getId().toString());

        //最后将用户的操作存入mq中
        mqMovementManager.sendMovement(userId,movement.getId(),MQMovementManager.MOVEMENT_PUBLISH);



        return ResponseEntity.ok(null);
    }

    public ResponseEntity findMyMovementByPage(Long userId, Integer pageNum, Integer pageSize) {
        //0.根据用户id查询userInfo
        UserInfo userInfo = userInfoService.findById(userId);

        //1.远程调用动态service获取当前页数据
        PageBeanVo pageBeanVo = movementService.findMyMovementByPage(userId, pageNum, pageSize);

        //2.获取pageBeanVo中动态集合(动态集合)
        List<Movement> items = (List<Movement>) pageBeanVo.getItems();

        //3.遍历动态集合,获取每个动态
        List<MovementVo> voList = new ArrayList<>();

        if (CollUtil.isNotEmpty(items)) {
            items.forEach(movement->{
                //4.创建movementVo,封装动态和userInfo
                MovementVo vo = new MovementVo();

                //先封装userInfo,后封装动态
                vo.setUserInfo(userInfo);
                vo.setMovement(movement);

                //判断当前用户是否对此动态点赞过
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE,userId,movement.getId()))) {
                    vo.setHasLiked(1);
                }

                //5.将每个审核通过的vo放入voList中
                if (movement.getState()==1) {
                    voList.add(vo);
                }
            });
        }
        //6.给pageBeanVo设置voList,且返回
        pageBeanVo.setItems(voList);
        return ResponseEntity.ok(pageBeanVo);
    }

    public ResponseEntity findFriendMovementByPage(Integer pageNum, Integer pageSize) {
        //1.获取当前用户id
        Long userId = UserHolder.get().getId();

        //2.远程调用动态service获取数据
        PageBeanVo pageBeanVo = movementService.findFriendMovementByPage(userId, pageNum, pageSize);

        //3.从PageBeanVo中获取动态集合
        List<Movement> items = (List<Movement>) pageBeanVo.getItems();

        //4.遍历动态集合,获取每个动态,获取动态发布人的userInfo,
        List<MovementVo> voList = new ArrayList<>();

        if (CollUtil.isNotEmpty(items)) {
            items.forEach(movement -> {
                //获取动态发布人的userInfo
                UserInfo userInfo = userInfoService.findById(movement.getUserId());

                //创建MovementVo,封装userInfo和动态,将每个vo放入voList中
                MovementVo vo = new MovementVo();

                //先封装userInfo,后封装movement
                vo.setUserInfo(userInfo);
                vo.setMovement(movement);

                //判断当前用户是否对此动态点赞过
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE,userId,movement.getId()))) {
                    vo.setHasLiked(1);
                }

                //将每个vo放入voList中
                if (movement.getState()==1) {
                    voList.add(vo);
                }
            });
        }

        //6.给pageBeanVo设置voList,且返回
        pageBeanVo.setItems(voList);
        return ResponseEntity.ok(pageBeanVo);
    }

    public ResponseEntity findRecommendMovementByPage(Integer pageNum, Integer pageSize) {
        //1.获取当前用户id
        Long userId = UserHolder.get().getId();

        //2.远程调用动态service获取pageBeanVo
        PageBeanVo pageBeanVo = movementService.findRecommendMovementByPage(userId, pageNum, pageSize);

        //3.获取pageBeanVo中动态集合
        List<Movement> items = (List<Movement>) pageBeanVo.getItems();

        //4.遍历动态集合,获取每个动态,获取动态发布人的userInfo,
        List<MovementVo> voList = new ArrayList<>();

        if (CollUtil.isNotEmpty(items)) {
            items.forEach(movement -> {
                //获取动态发布人的userInfo,
                UserInfo userInfo = userInfoService.findById(movement.getUserId());

                //创建MovementVo,封装userInfo和动态,
                MovementVo vo = new MovementVo();
                vo.setUserInfo(userInfo);
                vo.setMovement(movement);

                //判断当前用户是否对此动态点赞过
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE,userId,movement.getId()))) {
                    vo.setHasLiked(1);
                }

                //判断当前用户是否对此动态喜欢过
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LOVE,userId,movement.getId()))) {
                    vo.setHasLoved(1);
                }

                //将每个vo放入voList中
                voList.add(vo);
            });
        }

        //6.给pageBeanVo设置voList,且返回
        pageBeanVo.setItems(voList);
        return ResponseEntity.ok(pageBeanVo);
    }

    public ResponseEntity movementLike(ObjectId publishId) {
        //1.获取当前用户id
        Long userId = UserHolder.get().getId();

        //2.根据id查询动态详情,获取发布人id
        Movement movement = movementService.findById(publishId);

        //3.封装comment对象
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(publishId);
        comment.setCommentType(1);
        comment.setUserId(userId);
        comment.setPublishUserId(movement.getUserId());

        //4.远程调用service完成保存
        int count = commentService.save(comment);

        //5.在redis中保存用户点赞标识 movement_like:用户id_动态id  值:随便写1
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.MOVEMENT_LIKE,userId,publishId),"1");

        //最后将用户的操作存入mq中
        mqMovementManager.sendMovement(userId,movement.getId(),MQMovementManager.MOVEMENT_LIKE);

        //6.返回最新点赞数量
        return ResponseEntity.ok(count);
    }

    public ResponseEntity movementDisLike(ObjectId publishId) {
        //1.获取当前用户id
        Long userId = UserHolder.get().getId();

        //2.远程调用service完成取消点赞操作
        int count = commentService.delete(userId, publishId, 1);

        //3.删除用户点赞的标识
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.MOVEMENT_LIKE,userId,publishId));

        //最后将用户的操作存入mq中
        mqMovementManager.sendMovement(userId,publishId,MQMovementManager.MOVEMENT_DISLIKE);

        //4.返回数量
        return ResponseEntity.ok(count);
    }

    public ResponseEntity movementLove(ObjectId publishId) {
        //1.获取当前用户id
        Long userId = UserHolder.get().getId();

        //2.根据id查询动态详情,获取发布人id
        Movement movement = movementService.findById(publishId);

        //3.封装comment对象
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(publishId);
        comment.setCommentType(3);
        comment.setUserId(userId);
        comment.setPublishUserId(movement.getUserId());

        //4.远程调用service完成保存
        int count = commentService.save(comment);

        //5.在redis中保存用户喜欢标识
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.MOVEMENT_LOVE,userId,publishId),"1");

        //最后将用户的操作存入mq中
        mqMovementManager.sendMovement(userId,movement.getId(),MQMovementManager.MOVEMENT_LOVE);

        //6.返回最新喜欢数量
        return ResponseEntity.ok(count);
    }

    public ResponseEntity movementUnLove(ObjectId publishId) {
        //1.获取用户id
        Long userId = UserHolder.get().getId();
        //2.远程调用service删除喜欢
        int count = commentService.delete(userId, publishId, 3);
        //3.移除redis中喜欢的标识
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.MOVEMENT_LOVE,userId,publishId));

        //最后将用户的操作存入mq中
        mqMovementManager.sendMovement(userId,publishId,MQMovementManager.MOVEMENT_DISLOVE);

        //4.返回最新的喜欢数量
        return ResponseEntity.ok(count);
    }

    public ResponseEntity findById(ObjectId movementId) {
        //1.通过动态id获取动态详情
        Movement movement = movementService.findById(movementId);

        //2.获取动态发布人id,调用userInfoService查询userInfo
        UserInfo userInfo = userInfoService.findById(movement.getUserId());

        //3.封装MovementVo且返回
        MovementVo vo = new MovementVo();
        //先封装userInfo,再封装movement
        vo.setUserInfo(userInfo);
        vo.setMovement(movement);

        //最后将用户的操作存入mq中
        mqMovementManager.sendMovement(UserHolder.get().getId(), movement.getId(),MQMovementManager.MOVEMENT_BROWSE);

        return ResponseEntity.ok(vo);
    }

    public ResponseEntity findCommentByPage(ObjectId movementId, Integer pageNum, Integer pageSize) {
        //1.远程调用评论service获取数据
        PageBeanVo pageBeanVo = commentService.findCommentByPage(movementId, pageNum, pageSize, 2);

        //2.获取评论列表
        List<Comment> items = (List<Comment>) pageBeanVo.getItems();

        //3.遍历评论列表,获取每个评论,获取评论发布人id,获取发布人userInfo,封装CommentVo,将每个vo存放到voList中
        List<CommentVo> voList = new ArrayList<>();

        if (CollUtil.isNotEmpty(items)) {
            items.forEach(comment -> {
                // 获取评论发布人id,获取评论发布人userInfo,
                UserInfo userInfo = userInfoService.findById(comment.getUserId());

                // 封装CommentVo,
                CommentVo vo = new CommentVo();
                vo.setId(comment.getId().toString());
                vo.setAvatar(userInfo.getAvatar());
                vo.setNickname(userInfo.getNickname());
                vo.setContent(comment.getContent());
                vo.setCreateDate(DateUtil.formatDateTime(new Date(comment.getCreated())));

                // 将每个vo存放到voList中
                voList.add(vo);
            });
        }

        //4.将voList设置给pageBeanvo,将PageBeanVo返回
        pageBeanVo.setItems(voList);
        return ResponseEntity.ok(pageBeanVo);
    }

    public ResponseEntity movementComment(Map<String, String> map) {
        // 判断用户是否被冻结
        if (stringRedisConfig.stringRedisTemplate2().hasKey("Free2"+ UserHolder.get().getId())) {
            return ResponseEntity.status(500).body("此用户处于冻结发言状态");
        }
        //0.获取动态id和评论内容
        String movementId = map.get("movementId");
        String content = map.get("comment");

        //1.用户id
        Long userId = UserHolder.get().getId();

        //2.获取动态详情
        Movement movement = movementService.findById(new ObjectId(movementId));

        //3.封装comment
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(new ObjectId(movementId));
        comment.setCommentType(2);
        comment.setUserId(userId);
        comment.setPublishUserId(movement.getUserId());
        comment.setContent(content);//评论内容

        //4.远程调用service完成保存操作
        int count = commentService.save(comment);

        //最后将用户的操作存入mq中
        mqMovementManager.sendMovement(userId,movement.getId(),MQMovementManager.MOVEMENT_COMMENT);

        //5.返回最新的数量
        return ResponseEntity.ok(count);
    }
}
